package Queue;
//循环队列
//--front->---------------------
//  | 10 | 52 | 45 | 67  | 79 |
//--rear->----------------------
public class CircularQueue {
    private int usedSize;
    public int[] elem;
    public int front;
    public int rear;
    public CircularQueue(int k) {
        elem=new int[k];
    }

    public boolean enQueue(int value) {
        if(isFull()) {
            return false;
        }
        // if(rear==elem.length) {                //这边可以这样写的原因:即使rear==elem.length，那么队尾的数据依旧还是rear-1
        //     rear%=elem.length;
        // }
        elem[rear]=value;
        //rear++;
        rear=(rear+1)%elem.length;
        usedSize++;
        return true;
    }

    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        // if(front==elem.length) {              //不能这么写的原因是:当front为elem.length时,此时如果要取队头的数据,那么就会越界
        //     front%=elem.length;               //如果非要这么写，那么就要在取队头元素是进行判断，如果删除了最后一个元素，那么
        // }                                     //队头元素就是下标为0的元素
        // front++;
        front=(front+1)%elem.length;
        usedSize--;
        return true;
    }

    public int Front() {
        if(isEmpty()) {                      //队头的元素随着你的删除，front移动，而front移到哪里，哪里的数据就是对头得数据
            return -1;
        }
        // if(front==elem.length) {
        //     return elem[0];
        // }
        return elem[front];
    }

    public int Rear() {
        if(isEmpty()) {                       //如果数组为空，那么就不会有队尾的数据
            return -1;                        //但是如果rear是在插入完最后一个元素时回到0位置时
        }
        return elem[(rear==0)?elem.length-1:rear-1];//那么rear就会为0,而队尾的数据是数组的最后一个元素
        //return elem[rear-1];                 //如果rear不是从最后一个回到0,那么队尾的元素就是他的前一个下标
    }

    public boolean isEmpty() {
        return usedSize==0;
    }

    public boolean isFull() {
        return usedSize==elem.length;
    }
}
